在我們之前的練習都只有使用var宣告變數,其實還有其它兩個宣告方式可以使用。
接下來我們會學習使用let丶const更嚴謹的方式來撰寫程式碼!
首先我們想當然爾,在程式中由上而下,以下我們會先示範正常的情形,與容易造成錯誤的情形。
塊級作用域會解釋在最下面,若有變數概念的可以直接滑至最下方閱讀"block scope"
var name = 'Jessica'
console.log(name) //Jessica
以上當然會正常顯示Jessica
但我們先把輸出變數移到定義變數之前
console.log(name)
var name = 'Jessica' //undefined
可能跟你所想的不太一樣,var並不會讓程式停住,而是會變成undefined也就是尚未定義的意思
跟以下情況一樣
var name;
console.log(name); //undefined
重新宣告變數呢?
var name = 'Ian'
var name = 'Jessica'
console.log(name); //Jessica
是可以執行的
總結var宣告變數,使用非常寬鬆的規定,並且會造成難以預知的錯誤
這也是在ES6之後新增了let、const 可以讓JavaScript避免太多這種問題
正常情況下
let name = 'Jessica'
console.log(name) //Jessica
參考錯誤
console.log(name)
let name = 'Jessica' //ReferenceError: Cannot access 'name' before initialization
修改變數的值呢?
let name = 'Ian'
name = 'Jessica'
console.log(name); //Jessica
再次定義呢?
let name = 'Ian'
let name = 'Jessica'
console.log(name); //SyntaxError: Identifier 'name' has already been declared
再次宣告則不行
總結let的特性:
const name = 'Jessica'
name = 'Ian'
console.log(name); //TypeError: Assignment to constant variable.
再次定義覆蓋呢?
const name = 'Jessica'
const name = 'Ian'
console.log(name); //TSyntaxError: Identifier 'name' has already been declared
也不行
前面先輸出變數後定義也不行!!!
console.log(name)
const name = 'Jessica' //ReferenceError: Cannot access 'name' before initialization
但...若是物件或是陣列,可以透過修改property達到修改的效果
物件
const user = {
name: 'Ian'
}
user.name = 'Jessica'
console.log(user.name); //Jessica
陣列
const arrayTemp = [1,2,3]
arrayTemp[0] = 4
console.log(arrayTemp); //[ 4, 2, 3 ]
最後對於const的總結
若是修改值或是屬性是可以的,但重新定義、或宣告都是無效。
更簡單好記的方式
想像當我們用const定義好變數,相當於把變數想成101,101的地址已經申請並審核過了,而我們可以修改101裡面商品的櫃位、價格,但不能把它重新定義也就是移到新光三越等地方,這樣是不是更容易記呢!!!
reference也就是去抓取變數的地址(也就是記憶體位置)而已
const arrayTemp = [1,2,3]
arrayTemp = [4,2,3] //TypeError: Assignment to constant variable.
console.log(arrayTemp);
塊級作用域{ }為一個區塊,外層無法存取內層之變數
不同於let、const
以下程式碼雖然我們是在for迴圈內定義var i = 0,但當for loop結束,在外層一樣可以存取到i的值為5,稱之為全域汙染
for(var i = 0; i < 5; i++){
console.log(i);
}
console.log(`out of the block variable:${i}`)
/*
0
1
2
3
4
out of the block variable:5
*/
而let 與const則不同,會出現not defined
for(let i = 0; i < 5; i++){
console.log(i);
}
console.log(`out of the block variable:${i}`)
/*
0
1
2
3
4
ReferenceError: i is not defined
*/